home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
thesrc10.zip
/
COMMUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-12
|
68KB
|
2,143 lines
/***********************************************************************/
/* COMMUTIL.C - */
/* This file contains all utility functions used when processing */
/* commands. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991,1992 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@itc.gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 7877
* QLD 4121
* Australia
*/
#include <stdio.h>
#include <stdlib.h>
#include "the.h"
#include "key.h"
#include "command.h"
/*#define DEBUG 1*/
#define NUMBER_VALID_TARGETS 32
#define NUMBER_SEARCH_TARGETS 9
static SEARCH_TARGET st[NUMBER_VALID_TARGETS] =
{
{(unsigned char *)"\\",1,'\\',DIRECTION_FORWARD},
{(unsigned char *)"+\\",2,'\\',DIRECTION_FORWARD},
{(unsigned char *)"-\\",2,'\\',DIRECTION_BACKWARD},
{(unsigned char *)"/",1,'/',DIRECTION_FORWARD},
{(unsigned char *)"+/",2,'/',DIRECTION_FORWARD},
{(unsigned char *)"-/",2,'/',DIRECTION_BACKWARD},
{(unsigned char *)"@",1,'@',DIRECTION_FORWARD},
{(unsigned char *)"+@",2,'@',DIRECTION_FORWARD},
{(unsigned char *)"-@",2,'@',DIRECTION_BACKWARD},
{(unsigned char *)":",1,0,0},
{(unsigned char *)"*",1,0,0},
{(unsigned char *)"-*",2,0,0},
{(unsigned char *)"0",1,0,0},
{(unsigned char *)"1",1,0,0},
{(unsigned char *)"2",1,0,0},
{(unsigned char *)"3",1,0,0},
{(unsigned char *)"4",1,0,0},
{(unsigned char *)"5",1,0,0},
{(unsigned char *)"6",1,0,0},
{(unsigned char *)"7",1,0,0},
{(unsigned char *)"8",1,0,0},
{(unsigned char *)"9",1,0,0},
{(unsigned char *)"-0",1,0,0},
{(unsigned char *)"-1",1,0,0},
{(unsigned char *)"-2",1,0,0},
{(unsigned char *)"-3",1,0,0},
{(unsigned char *)"-4",1,0,0},
{(unsigned char *)"-5",1,0,0},
{(unsigned char *)"-6",1,0,0},
{(unsigned char *)"-7",1,0,0},
{(unsigned char *)"-8",1,0,0},
{(unsigned char *)"-9",1,0,0}
};
unsigned char temp_cmd[150];
unsigned char temp_params[150];
#define MAX_CMDS 15
static unsigned char cmd[MAX_CMDS][80];
static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
bool clear_command=TRUE;
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern char number_of_views;
extern WINDOW *foot,*error_window;
extern char error_on_screen;
extern unsigned char *rec;
extern unsigned short rec_len;
extern unsigned char *cmd_rec;
extern unsigned short cmd_rec_len;
extern unsigned char in_profile; /* indicates if processing profile */
extern unsigned char file_read; /* indicates if we have read the file */
extern unsigned char *last_target;
extern unsigned char curr_path[MAX_FILE_NAME+1] ;
extern unsigned char sp_path[MAX_FILE_NAME+1] ;
extern unsigned char sp_fname[MAX_FILE_NAME+1] ;
/*---------------------- function definitions -------------------------*/
#ifdef PROTO
void split_command(unsigned char *,unsigned char *,unsigned char *);
int param_split(unsigned char *,unsigned char *[],int );
long valid_target(unsigned char *);
long search_target(unsigned char *,unsigned char,long,unsigned char);
short find_command(unsigned char *);
unsigned char next_char(LINE *,short *);
void cleanup_command_line(void);
short selective_change(unsigned char *,unsigned char *,long,long,short);
#else
void split_command();
int param_split();
long valid_target();
long search_target();
short find_command();
unsigned char next_char();
void cleanup_command_line();
short selective_change();
#endif
/***********************************************************************/
#ifdef PROTO
unsigned char *get_key_definition(unsigned short key)
#else
unsigned char *get_key_definition(key)
unsigned short key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
DEFINE *curr;
bool key_defined=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_key_definition");
#endif
/*---------------------------------------------------------------------*/
/* First determine if the key is a named key. */
/*---------------------------------------------------------------------*/
for (i=0;i<MAX_NUMBER_KEYS && key_defined == FALSE;i++)
{
if (key == key_table[i].key_value)
{
strcpy(temp_cmd,"Key: ");
key_defined = TRUE;
strcat(temp_cmd,key_table[i].mnemonic);
}
}
/*---------------------------------------------------------------------*/
/* If key not defined, show it as a character and decimal. Provided it */
/* is an ASCII or extended character. */
/*---------------------------------------------------------------------*/
if (!key_defined && key <256)
sprintf(temp_cmd,"Key: %c \\%d",(char)key,key);
/*---------------------------------------------------------------------*/
/* Next check to see if the key has been assigned. */
/*---------------------------------------------------------------------*/
curr = first_define;;
while(curr != NULL)
{
if (key == curr->def_funkey && curr->def_command != (-1))
{
strcat(temp_cmd," - assigned to '");
strcat(temp_cmd,command[curr->def_command].text);
if (strcmp(curr->def_params,"") != 0)
{
strcat(temp_cmd," ");
strcat(temp_cmd,curr->def_params);
}
strcat(temp_cmd,"'");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
curr = curr->def_next;
}
/*---------------------------------------------------------------------*/
/* If not, check for the default function key values. */
/*---------------------------------------------------------------------*/
for (i=0;i<MAX_COMMANDS;i++)
{
if (key == command[i].funkey)
{
strcat(temp_cmd," - assigned to '");
strcat(temp_cmd,command[i].text);
if (strcmp(command[i].params,"") != 0)
{
strcat(temp_cmd," ");
strcat(temp_cmd,command[i].params);
}
strcat(temp_cmd,"'");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
}
/*---------------------------------------------------------------------*/
/* If none of the above, it is unassigned */
/*---------------------------------------------------------------------*/
strcat(temp_cmd," - unassigned");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
/***********************************************************************/
#ifdef PROTO
int function_key(int key)
#else
int function_key(key)
int key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
register int i;
DEFINE *curr;
unsigned char cmd[81];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:function_key");
#endif
/*---------------------------------------------------------------------*/
/* First check to see if the function key has been redefined. */
/*---------------------------------------------------------------------*/
curr = first_define;
while(curr != NULL)
{
if (key == curr->def_funkey && curr->def_command != (-1))
{
i = (*command[curr->def_command].function)(curr->def_params);
#ifdef TRACE
trace_return();
#endif
return(i);
}
curr = curr->def_next;
}
/*---------------------------------------------------------------------*/
/* If not, check for the default function key values. */
/*---------------------------------------------------------------------*/
for (i=0;i<MAX_COMMANDS;i++)
if (key == command[i].funkey)
{
i = (*command[i].function)(command[i].params);
#ifdef TRACE
trace_return();
#endif
return(i);
}
#ifdef TRACE
trace_return();
#endif
return(RAW_KEY);
}
/***********************************************************************/
#ifdef PROTO
bool valid_set_command(char *cmd_line)
#else
bool valid_set_command(cmd_line)
unsigned char *cmd_line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:valid_set_command");
#endif
for (i=0;i<MAX_COMMANDS;i++)
{
/*---------------------------------------------------------------------*/
/* If no command text, continue. */
/*---------------------------------------------------------------------*/
if (strcmp(command[i].text,"") == 0)
continue;
/*---------------------------------------------------------------------*/
/* Check that the supplied command matches the command for the length */
/* of the command and that the length is at least as long as the */
/* necessary significance. */
/*---------------------------------------------------------------------*/
if (equal(command[i].text,cmd_line,command[i].min_len)
&& command[i].min_len != 0)
{
#ifdef TRACE
trace_return();
#endif
return(command[i].set_command);
}
}
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
/***********************************************************************/
#ifdef PROTO
int command_line(char *cmd_line)
#else
int command_line(cmd_line)
unsigned char *cmd_line;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern LINE *first_profile_command,*current_profile_command;
/*--------------------------- local data ------------------------------*/
unsigned short x,y,valid_command;
register int i;
unsigned char *cmd,*params;
int rc;
long num_lines;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:command_line");
#endif
/*---------------------------------------------------------------------*/
/* If the command line is blank, just return. */
/*---------------------------------------------------------------------*/
if (strlen(cmd_line) == 0)
{
if (!in_profile)
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* If the command is to be kept displayed on the command line... */
/*---------------------------------------------------------------------*/
if (*(cmd_line) == '&')
{
clear_command = FALSE;
split_command(cmd_line+1,temp_cmd,temp_params);
}
else
{
clear_command = TRUE;
split_command(cmd_line,temp_cmd,temp_params);
}
/*---------------------------------------------------------------------*/
/* Here is where we could check for synonyms first. */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* Look up the command in the command array in command.h */
/*---------------------------------------------------------------------*/
valid_command = NO;
for (i=0;i<MAX_COMMANDS;i++)
{
/*---------------------------------------------------------------------*/
/* If no command text, continue. */
/*---------------------------------------------------------------------*/
if (strcmp(command[i].text,"") == 0)
continue;
/*---------------------------------------------------------------------*/
/* Check that the supplied command matches the command for the length */
/* of the command and that the length is at least as long as the */
/* necessary significance. */
/*---------------------------------------------------------------------*/
if (equal(command[i].text,temp_cmd,command[i].min_len)
&& command[i].min_len != 0)
{
if (in_profile
&& !command[i].valid_profile_command)
{
display_error(25,command[i].text);
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
valid_command = YES;
if (in_profile)
{
if ((command[i].set_command && file_read == NO)
|| file_read == YES)
rc = (*command[i].function)(temp_params);
else
{
if ((current_profile_command = add_line(first_profile_command,
current_profile_command,
cmd_line,
strlen(cmd_line))) == NULL)
{
display_error(30,"");
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if (first_profile_command == NULL)
first_profile_command = current_profile_command;
}
}
else
rc = (*command[i].function)(temp_params);
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
/*---------------------------------------------------------------------*/
/* To get here, the command line does not contain a valid command... */
/* ...so, check to see if the command line is a valid target. */
/* Before we do that, if we are still in the profile file then if we */
/* actually have a potential valid target, then we have to save the */
/* command for later processsing when we have a file to search through.*/
/*---------------------------------------------------------------------*/
if (in_profile && file_read == NO)
{
for (i=0;i<NUMBER_VALID_TARGETS;i++)
{
if (strncmp(temp_cmd,st[i].prefix,st[i].length) == 0)
{
if ((current_profile_command = add_line(first_profile_command,
current_profile_command,
temp_cmd,
strlen(temp_cmd))) == NULL)
{
display_error(30,"");
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if (first_profile_command == NULL)
first_profile_command = current_profile_command;
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(OK);
}
}
}
num_lines = valid_target(temp_cmd);
if (num_lines == TARGET_NOT_FOUND)
{
valid_command = YES;
display_error(17,"");
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if (num_lines != TARGET_ERROR)
{
sprintf(temp_cmd,"%-ld",num_lines);
if (in_profile && file_read == NO)
{
if ((current_profile_command = add_line(first_profile_command,
current_profile_command,
temp_cmd,
strlen(temp_cmd))) == NULL)
{
display_error(30,"");
cleanup_command_line();
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if (first_profile_command == NULL)
first_profile_command = current_profile_command;
}
else
{
rc = Next(temp_cmd);
}
valid_command = YES;
}
cleanup_command_line();
if (!valid_command)
{
display_error(21,temp_cmd);
rc = OK;
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
void cleanup_command_line(void)
#else
void cleanup_command_line()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:cleanup_command_line");
#endif
if (in_profile || number_of_views == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (clear_command)
{
/* for (i=0;i<CURRENT_SCREEN.screen_cols-PREFIX_WIDTH;i++)
mvwaddch(CURRENT_WINDOW_COMMAND,0,i,' '); */
wmove(CURRENT_WINDOW_COMMAND,0,0);
wclrtoeol(CURRENT_WINDOW_COMMAND);
memset(cmd_rec,' ',COLS);
cmd_rec_len = 0;
}
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void split_command(unsigned char *cmd_line,unsigned char *cmd,
unsigned char *params)
#else
void split_command(cmd_line,cmd,params)
unsigned char *cmd_line;
unsigned char *cmd;
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short pos;
unsigned char *param_ptr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:split_command");
#endif
strcpy(cmd,cmd_line);
if ((param_ptr = (unsigned char *)strpbrk(cmd," \\/-+@")) == NULL)
{
strcpy(params,"");
/* strcpy(cmd,cmd_line); */
#ifdef TRACE
trace_return();
#endif
return;
}
pos = strzne(param_ptr,' ');
if (param_ptr == cmd)
{
strcpy(params,"");
/* strcpy(cmd,cmd_line); */
#ifdef TRACE
trace_return();
#endif
return;
}
strcpy(params,param_ptr+pos);
*(param_ptr) = '\0';
/* strcpy(cmd,cmd_line);*/
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
int param_split(unsigned char *params,unsigned char *word[],int words)
#else
int param_split(params,word,words)
unsigned char *params;
unsigned char *word[];
int words;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
unsigned short len;
unsigned char j,end_of_string;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:param_split");
#endif
for (i=0;i<words;i++)
word[i] = (unsigned char *)"";
j = 0;
end_of_string = YES;
len = strlen(params);
for (i=0;i<len && j<words;i++)
if (*(params+i) == ' ' || *(params+i) == '\t')
{
*(params+i) = '\0';
end_of_string = YES;
}
else
if (end_of_string == YES)
{
word[j++] = params+i;
end_of_string = NO;
}
#ifdef TRACE
trace_return();
#endif
return(j);
}
/***********************************************************************/
#ifdef PROTO
long valid_target(unsigned char *target)
#else
long valid_target(target)
unsigned char *target;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* This returns TARGET_ERROR if the target value is invalid. Otherwise */
/* it returns the number of lines to the target from the 'true_line'. */
/* The 'true_line' is either the 'current_line' (if in WINDOW_COMMAND) */
/* or 'focus_line' if elsewhere. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
long num_target;
unsigned long true_line;
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:valid_target");
#endif
/*---------------------------------------------------------------------*/
/* Determine 'true_line'. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| in_profile)
true_line = CURRENT_VIEW->current_line;
else
true_line = CURRENT_VIEW->focus_line;
/*---------------------------------------------------------------------*/
/* Check for '*'. This means to the end of file. */
/*---------------------------------------------------------------------*/
if (*(target) == '*')
{
#ifdef TRACE
trace_return();
#endif
return(CURRENT_FILE->number_lines - true_line+1);
}
/*---------------------------------------------------------------------*/
/* Check for '-*'. This means to the top of file. */
/*---------------------------------------------------------------------*/
if (strncmp(target,"-*",2) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(true_line*(-1));
}
/*---------------------------------------------------------------------*/
/* Check for search targets. These are delimited by one of '/\@' and */
/* may be positive or negative. */
/*---------------------------------------------------------------------*/
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (strncmp(target,st[i].prefix,st[i].length) == 0)
{
/*---------------------------------------------------------------------*/
/* Save valid target for later retrieval. */
/*---------------------------------------------------------------------*/
if (strcmp(target+st[i].length,"") != 0)
strcpy(last_target,target);
num_target = search_target((target+st[i].length),st[i].delim,
true_line,st[i].direction);
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/*---------------------------------------------------------------------*/
/* Check for ':' - absolute line number target. */
/*---------------------------------------------------------------------*/
if (*(target) == ':')
{
target++;
if (!valid_integer(target))
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
num_target = atol(target);
if (num_target < 0L) /* invalid if negative */
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
if (num_target >= true_line)
num_target = min((num_target - true_line),
(CURRENT_FILE->number_lines - true_line+1));
else
num_target = (true_line - num_target)*(-1);
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/*---------------------------------------------------------------------*/
/* Lastly, check for valid integers, +ve or -ve. */
/*---------------------------------------------------------------------*/
if (!valid_integer(target))
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
num_target = atol(target);
if (num_target >= 0)
num_target = min(num_target,(CURRENT_FILE->number_lines - true_line+1));
else
{
/* int temp_aa;
if (true_line == 0)
temp_aa = 0;
else
temp_aa = true_line * (-1);
num_target = max((num_target),temp_aa); */
num_target = max((num_target),(true_line == 0) ? (0) : (int)(true_line*(-1)));
}
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/***********************************************************************/
#ifdef PROTO
long search_target(unsigned char *target,unsigned char delim,
long true_line,unsigned char direction)
#else
long search_target(target,delim,true_line,direction)
unsigned char *target;
unsigned char delim,direction;
long true_line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short start_col=0;
long rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:search_target");
#endif
if (*(target+strlen(target)-1) == delim)
*(target+strlen(target)-1) = '\0';
rc = find_string(true_line,&start_col,target,strlen(target),
direction,direction,CURRENT_VIEW->case_locate);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int get_row_for_focus_line(int cr,long fl,long cl)
#else
int get_row_for_focus_line(cr,fl,cl)
int cr;
long fl,cl;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* Returns the row within the main window where the focus line is */
/* placed. If the focus line is off the screen, or out of bounds of the*/
/* current size of the file; <0 or >number_lines, this returns the */
/* current row. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
register int row;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_row_for_focus_line");
#endif
row = (cr + (int)(fl - cl));
if (fl <= row)
{
#ifdef TRACE
trace_return();
#endif
return(row);
}
if (row < 0 || row > min(CURRENT_SCREEN.rows - 1,CURRENT_FILE->number_lines+1))
{
#ifdef TRACE
trace_return();
#endif
return(cr);
}
#ifdef TRACE
trace_return();
#endif
return(row);
}
/***********************************************************************/
#ifdef PROTO
int calculate_focus_line(int cr,long fl,long cl)
#else
int calculate_focus_line(cr,fl,cl)
int cr;
long fl,cl;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* Returns the new focus line. If the focus line is still in the */
/* window, it stays as is. If not,the focus line becomes the current */
/* line. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
register int max_top,max_bot;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:calculate_focus_line");
#endif
max_top = max(0,cl-CURRENT_VIEW->current_row);
max_bot = min(CURRENT_FILE->number_lines+1,
cl+(CURRENT_SCREEN.rows - CURRENT_VIEW->current_row)-1);
if (fl >= max_top && fl <= max_bot)
{
#ifdef TRACE
trace_return();
#endif
return(fl);
}
#ifdef TRACE
trace_return();
#endif
return(cl);
}
/***********************************************************************/
#ifdef PROTO
void print_line(char close_spooler,long num_lines,short pagesize,
unsigned char *text,
unsigned char *line_term)
#else
void print_line(close_spooler,num_lines,pagesize,text,line_term)
char close_spooler;
long num_lines;
short pagesize;
unsigned char *text;
unsigned char *line_term;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
#if !defined(DOS) && !defined(OS2)
extern unsigned char *spooler_name;
#endif
/*--------------------------- local data ------------------------------*/
#if !defined(DOS) && !defined(OS2)
static char spooler_open=NO;
static FILE *pp;
#endif
register int i;
long j;
LINE *curr;
unsigned char c;
unsigned short line_number=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:print_line");
#endif
if (close_spooler == YES)
{
#if !defined(DOS) && !defined(OS2)
if (spooler_open == YES)
pclose(pp);
#endif
#ifdef TRACE
trace_return();
#endif
return;
}
#if !defined(DOS) && !defined(OS2)
if (spooler_open == NO)
{
pp = popen(spooler_name,"w");
spooler_open = YES;
}
#endif
if (num_lines == 0L)
{
fprintf(
#if !defined(DOS) && !defined(OS2)
pp,
#else
stdprn,
#endif
"%s%s",text,line_term);
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Determine where to start writing from in the linked list. */
/*---------------------------------------------------------------------*/
/* we are actually going to print file contents */
curr = ll_find(CURRENT_FILE->first_line,CURRENT_VIEW->current_line);
/*---------------------------------------------------------------------*/
/* Now write out the contents of the file array to the printer. */
/*---------------------------------------------------------------------*/
for (j=0L;j<num_lines && curr->next != NULL;j++)
{
if (curr->prev != NULL) /* not first line */
{
for (i=0;i<curr->length;i++)
fputc(*(curr->line+i),
#if !defined(DOS) && !defined(OS2)
pp);
fputc('\n',pp);
#else
stdprn);
fputc('\r',stdprn);
fputc('\n',stdprn);
#endif
line_number++;
if (line_number == pagesize
&& pagesize != 0)
{
#if !defined(DOS) && !defined(OS2)
fputc('\f',pp);
#else
fputc('\f',stdprn);
#endif
line_number = 0;
}
}
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
unsigned char next_char(LINE *curr,short *off)
#else
unsigned char next_char(curr,off)
LINE *curr;
short *off;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:next_char");
#endif
if (*(off) < curr->length)
{
(*(off))++;
#ifdef TRACE
trace_return();
#endif
return(*(curr->line+((*(off))-1)));
}
*(off) = (-1);
#ifdef TRACE
trace_return();
#endif
return(0);
}
/***********************************************************************/
#ifdef PROTO
int add_define(unsigned char *mnemonic,unsigned char *cmd,
unsigned char *params)
#else
int add_define(mnemonic,cmd,params)
unsigned char *mnemonic,*cmd,*params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short key_value,cmd_nr;
DEFINE *temp;
register short i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_define");
#endif
if (strcmp(mnemonic,"") == 0) /* first dummy add */
{
if ((first_define = (DEFINE *)memMalloc(sizeof(DEFINE),
"first define")) == NULL)
{
display_error(30,"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
first_define->def_command = (-1);
first_define->def_params = NULL;
first_define->def_next = NULL;
first_define->def_funkey = 0;
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* This could be cleaner. It should check to see if the combination of */
/* command and key_value are already in the list or are set in the list*/
/* of default commands. */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* Ensure that the mnemonic is upper case before we test it. */
/*---------------------------------------------------------------------*/
/* for (i=0;i<strlen(mnemonic);i++)
if (islower(*(mnemonic+i)))
*(mnemonic+i) = toupper(*(mnemonic+i));
*/
/*---------------------------------------------------------------------*/
/* First check the mnemonic for decimal string value. ie begins with \ */
/*---------------------------------------------------------------------*/
if (*(mnemonic) == '\\')
{
if ((key_value = atoi(mnemonic+1)) == 0)
{
display_error(13,mnemonic);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
}
else
{
if ((key_value = find_key_value(mnemonic)) == ERROR)
{
display_error(13,mnemonic);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
}
/*---------------------------------------------------------------------*/
/* Ensure that the cmd is lower case before we test it. */
/*---------------------------------------------------------------------*/
for (i=0;i<strlen(cmd);i++)
if (isupper(*(cmd+i)))
*(cmd+i) = tolower(*(cmd+i));
if ((cmd_nr = find_command(cmd)) == ERROR)
{
display_error(21,cmd);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
/*---------------------------------------------------------------------*/
/* Before we allocate any memory, check that combined length of cmd, a */
/* space and the parameters are less than 80. */
/*---------------------------------------------------------------------*/
if (strlen(cmd)+strlen(params)+1 > 80)
{
display_error(37,"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if ((temp = (DEFINE *)memMalloc(sizeof(DEFINE),mnemonic)) == NULL)
{
display_error(30,"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
temp->def_next = first_define->def_next;
first_define->def_next = temp;
temp->def_funkey = key_value;
if ((temp->def_params = (unsigned char *)memMalloc(strlen(params)+1,params)) == NULL)
{
display_error(30,"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
strcpy(temp->def_params,params);
temp->def_command = cmd_nr;
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
int find_key_value(unsigned char *mnemonic)
#else
int find_key_value(mnemonic)
unsigned char *mnemonic;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_key_value");
#endif
for (i=0;i<MAX_NUMBER_KEYS;i++)
if (strcmp(mnemonic,key_table[i].mnemonic) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(key_table[i].key_value);
}
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
/***********************************************************************/
#ifdef PROTO
short find_command(unsigned char *cmd)
#else
short find_command(cmd)
unsigned char *cmd;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_command");
#endif
for (i=0;i<MAX_COMMANDS;i++)
if (strcmp(cmd,command[i].text) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(i);
}
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
/***********************************************************************/
#ifdef PROTO
short split_change_params(char *cmd_line,char *old_str,char *new_str,char *target,
char *num,char *occ)
#else
short split_change_params(cmd_line,old_str,new_str,target,num,occ)
char *cmd_line,*old_str,*new_str,*target,*num,*occ;
#endif
/***********************************************************************/
{
register short i;
short off1,off2,off3,eos_old,eos_new,target_start;
char cmmand_line[80],str3[20];
char *cmd=cmmand_line;
#define SPLT_PARAMS 3
unsigned char *word[SPLT_PARAMS];
char parm[SPLT_PARAMS];
unsigned short num_params;
unsigned short x,y;
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:split_change_params");
#endif
strcpy(cmd,cmd_line);
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (*(cmd) == st[i].delim)
break;
if (i == NUMBER_SEARCH_TARGETS)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/*---------------------------------------------------------------------*/
/* Obtain the old string to change. */
/*---------------------------------------------------------------------*/
if ((off1 = strzeq(cmd+1,st[i].delim)) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
eos_old = off1+1;
*(cmd+eos_old) = '\0';
strcpy(old_str,cmd+1);
/*---------------------------------------------------------------------*/
/* Obtain the new string to change to. */
/*---------------------------------------------------------------------*/
if ((off2 = strzeq(cmd+eos_old+1,st[i].delim)) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
eos_new = eos_old+off2+1;
*(cmd+eos_new) = '\0';
strcpy(new_str,cmd+eos_old+1);
/*---------------------------------------------------------------------*/
/* Determine if there are any more parameters. If not, then return with*/
/* parameters of 1,1,1. */
/*---------------------------------------------------------------------*/
off1 = strzne(cmd+eos_new+1,' ');
if (off1 == (-1))
{
strcpy(target,"1");
strcpy(num,"1");
strcpy(occ,"1");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
target_start = eos_new+off1+1;
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (strncmp(cmd+target_start,st[i].prefix,st[i].length) == 0)
break;
if (i == NUMBER_SEARCH_TARGETS)
{ /* not a string target */
num_params = param_split(cmd+target_start,word,SPLT_PARAMS);
if (strcmp(word[0],"") == 0)
strcpy(target,"1");
else
strcpy(target,word[0]);
if (strcmp(word[1],"") == 0)
strcpy(num,"1");
else
strcpy(num,word[1]);
if (strcmp(word[2],"") == 0)
strcpy(occ,"1");
else
strcpy(occ,word[2]);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/* to get here it is a valid start to a string target */
off1 = strzeq(cmd+target_start+st[i].length,st[i].delim);
if (off1 == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
off2 = off1+1+st[i].length;
for (i=0;i<off2;i++)
str3[i] = *(cmd+target_start+i);
str3[off2] = '\0';
strcpy(target,str3);
num_params = param_split(cmd+target_start+off2+1,word,2);
if (strcmp(word[0],"") == 0)
strcpy(num,"1");
else
strcpy(num,word[0]);
if (strcmp(word[1],"") == 0)
strcpy(occ,"1");
else
strcpy(occ,word[1]);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
int free_define_memory(void)
#else
int free_define_memory()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
DEFINE *temp;
unsigned char first=TRUE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:free_define_memory");
#endif
temp = first_define;
while(temp != NULL)
{
if (!first)
memFree(temp->def_params,temp->def_params);
else
first = FALSE;
memFree(temp,"mnemonic");
temp = temp->def_next;
}
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
void init_command(void)
#else
void init_command()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:init_command");
#endif
for (i=0;i<MAX_CMDS;i++)
strcpy(cmd[i],"");
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void add_command(unsigned char *new_cmd)
#else
void add_command(new_cmd)
unsigned char *new_cmd;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_command");
#endif
offset_cmd = 0;
/*---------------------------------------------------------------------*/
/* If the command to be added is the same as the current command or if */
/* the command line is empty, return without adding command to array. */
/*---------------------------------------------------------------------*/
if (strcmp(new_cmd,cmd[current_cmd]) == 0
|| strcmp(new_cmd,"") == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (number_cmds == MAX_CMDS)
current_cmd = last_cmd = (last_cmd == MAX_CMDS-1) ? 0 : ++last_cmd;
else
current_cmd = ++last_cmd;
strcpy(cmd[current_cmd],new_cmd);
number_cmds++;
if (number_cmds > MAX_CMDS)
number_cmds = MAX_CMDS;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
unsigned char *get_command( char direction)
#else
unsigned char *get_command(direction)
char direction;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned char *cmd_to_return;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_command");
#endif
if (number_cmds == 0)
{
#ifdef TRACE
trace_return();
#endif
return((unsigned char *)NULL);
}
if (direction == DIRECTION_BACKWARD)
{
if (current_cmd+1 == number_cmds)
{
current_cmd = 0;
cmd_to_return = cmd[current_cmd];
}
else
cmd_to_return = cmd[++current_cmd];
}
else
{
if (current_cmd+offset_cmd < 0)
{
current_cmd = number_cmds-1;
cmd_to_return = cmd[current_cmd];
}
else
{
current_cmd = current_cmd+offset_cmd;
cmd_to_return = cmd[current_cmd];
}
}
offset_cmd = (-1);
#ifdef TRACE
trace_return();
#endif
return(cmd_to_return);
}
/***********************************************************************/
#ifdef PROTO
int execute_change_command(unsigned char *params,bool selective)
#else
int execute_change_command(params,selective)
unsigned char *params;
bool selective;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define ALT_PARAMS 4
unsigned char *word[ALT_PARAMS];
char parm[ALT_PARAMS];
register int i;
unsigned short num_params,len;
long num_lines,long_n,long_m;
unsigned short x,y;
LINE *curr;
char old_str[60],new_str[60],target[20],n[20],m[20];
short rc,selective_rc=OK;
char direction;
short number_lines,number_changes,number_of_changes,number_of_occ;
short start_col,real_start,real_end,loc;
long true_line,last_true_line,final_target;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_change_command");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. Up to 4 parameters */
/* may be supplied. The first is the string to change and its new */
/* value, the second is the target, the third is the number of times */
/* to change the value on one line and lastly is which occurrence to */
/* change first. */
/*---------------------------------------------------------------------*/
rc = split_change_params(params,old_str,new_str,target,n,m);
if (rc == (-1))
{
display_error(36,"");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
if ((num_lines = valid_target(target)) == TARGET_ERROR
|| CURRENT_FILE->number_lines == 0L)
{
display_error(17,target);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
if (strcmp(n,"*") == 0)
long_n = MAX_LONG;
else
if (!valid_positive_integer(n))
{
display_error(4,n);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
else
long_n = atol(n);
if (!valid_positive_integer(m))
{
display_error(4,m);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
else
long_m = atol(m);
if (num_lines < 0)
direction = DIRECTION_BACKWARD;
else
direction = DIRECTION_FORWARD;
/*---------------------------------------------------------------------*/
/* If the command was issued from the command window, the current_line */
/* is the line to start changing from, otherwise it is the focus_line. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
true_line = CURRENT_VIEW->current_line;
else
true_line = CURRENT_VIEW->focus_line;
final_target = true_line+num_lines;
/*---------------------------------------------------------------------*/
/* If the true_line is on the top or bottom of file lines and we are */
/* searching forward or backward respectively, set the true_line to be */
/* the next line in the appropriate direction. */
/*---------------------------------------------------------------------*/
if (true_line == 0
&& direction == DIRECTION_FORWARD)
true_line++;
if (true_line == CURRENT_FILE->number_lines+1
&& direction == DIRECTION_BACKWARD)
true_line--;
if (true_line != CURRENT_VIEW->focus_line)
{
post_process_line(CURRENT_VIEW->focus_line);
pre_process_line(true_line);
}
number_lines = 0;
number_changes = 0;
number_of_changes = 0;
number_of_occ = 0;
start_col = 0;
last_true_line = true_line;
curr = ll_find(CURRENT_FILE->first_line,true_line);
while(1)
{
loc = 0;
number_of_changes = number_of_occ = 0;
while(loc != (-1))
{
real_end = min(rec_len,CURRENT_VIEW->zone_end-1);
real_start = max(start_col,CURRENT_VIEW->zone_start-1);
if (rec_len < real_start && blank_field(old_str))
{
loc = 0;
rec_len = real_start;
}
else
{
if (CURRENT_VIEW->case_change == CASE_IGNORE)
loc = memposi(rec+real_start,
(real_end - real_start + 1),old_str,strlen(old_str));
else
loc = mempos(rec+real_start,
(real_end - real_start + 1),old_str,strlen(old_str));
}
if (loc != (-1))
{
start_col = loc+real_start;
if (number_of_changes <= long_n-1 && number_of_occ >= long_m-1)
{
/* the following block is done for change or confirm of sch */
if (!selective)
{
memdelchr(rec,start_col,rec_len,strlen(old_str));
rec_len -= strlen(old_str);
len = strlen(new_str);
meminsmem(rec,new_str,len,start_col,MAX_LINE_LENGTH,rec_len);
rec_len += len;
if (rec_len > MAX_LINE_LENGTH)
{
rec_len = MAX_LINE_LENGTH;
loc = (-1);
}
start_col += len;
number_changes++;
number_of_changes++;
}
else
{
/* selective */
selective_rc = selective_change(old_str,new_str,true_line,
last_true_line,start_col);
last_true_line = true_line;
switch(selective_rc)
{
case QUITOK:
case OK:
start_col += strlen(new_str);
number_changes++;
number_of_changes++;
if (rec_len > MAX_LINE_LENGTH)
{
rec_len = MAX_LINE_LENGTH;
loc = (-1);
}
break;
case SKIP:
start_col += strlen(old_str);
break;
case QUIT:
break;
}
if (selective_rc == QUIT || selective_rc == QUITOK)
break;
}
number_of_occ++;
}
else
{
start_col += strlen(old_str);
number_of_occ++;
}
if (number_of_changes > long_n-1)
/* || number_of_occ > long_n-1)*/
loc = (-1);
}
} /* end while */
if (number_of_changes != 0) /* changes made */
{
post_process_line(true_line);
number_lines++;
}
if (selective_rc == QUIT || selective_rc == QUITOK)
break;
true_line += direction;
start_col = 0;
if (direction == DIRECTION_FORWARD)
{
if (true_line >= final_target)
break;
curr = curr->next;
}
else
{
if (true_line <= final_target)
break;
curr = curr->prev;
}
pre_process_line(true_line);
}
/*---------------------------------------------------------------------*/
/* If no changes were made, display error message and return. */
/*---------------------------------------------------------------------*/
if (number_changes == 0)
{
display_error(36,"");
pre_process_line(CURRENT_VIEW->focus_line);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* If STAY is OFF, change the current and focus lines by the number */
/* of lines calculated from the target. */
/*---------------------------------------------------------------------*/
if (!CURRENT_VIEW->stay) /* stay is off */
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines;
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
sprintf(old_str,"%d occurrence(s) changed on %d line(s)",number_changes,number_lines);
display_error(0,old_str);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
short selective_change(unsigned char *old_str,unsigned char *new_str,
long true_line,long last_true_line,short start_col)
#else
short selective_change(old_str,new_str,true_line,last_true_line,start_col)
unsigned char *old_str;
unsigned char *new_str;
long true_line;
long last_true_line;
short start_col;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short y,x,rc;
long offset=true_line-last_true_line;
unsigned short key,len;
bool changed;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:selective_change");
#endif
getyx(CURRENT_WINDOW_MAIN,y,x);
/* move cursor to old string a la cmatch */
/* display message */
/* accept key F5 next, F6 change, Esc? to quit */
CURRENT_VIEW->focus_line = true_line;
if (offset + y <= 0
|| offset + y >= CURRENT_SCREEN.rows)
{
CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
y = CURRENT_VIEW->current_row;
}
else
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (start_col >= CURRENT_VIEW->verify_col-1
&& start_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
x = start_col-(CURRENT_VIEW->verify_col-1);
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,start_col-(short)x);
x = (start_col-(CURRENT_VIEW->verify_col-1));
}
key = 0;
changed = FALSE;
while(key == 0)
{
if (changed)
display_error(0,"Press 'N' for next,'C' to undo 'Q' to quit");
else
display_error(0,"Press 'N' for next,'C' to change 'Q' to quit");
touchwin(error_window);
show_page();
wnoutrefresh(CURRENT_WINDOW_MAIN);
wmove(CURRENT_WINDOW_MAIN,y,x);
doupdate();
key = my_getch(CURRENT_WINDOW_MAIN);
switch(key)
{
case 'N':
case 'n':
if (changed)
rc = OK;
else
rc = SKIP;
break;
case 'C':
case 'c':
if (changed)
{
len = strlen(new_str);
memdelchr(rec,start_col,rec_len,len);
rec_len -= len;
len = strlen(old_str);
meminsmem(rec,old_str,len,start_col,MAX_LINE_LENGTH,rec_len);
rec_len += len;
}
else
{
len = strlen(old_str);
memdelchr(rec,start_col,rec_len,len);
rec_len -= len;
len = strlen(new_str);
meminsmem(rec,new_str,len,start_col,MAX_LINE_LENGTH,rec_len);
rec_len += len;
}
changed = (changed) ? FALSE : TRUE;
key = 0;
break;
case 'Q':
case 'q':
if (changed)
rc = QUITOK;
else
rc = QUIT;
break;
default:
key = 0;
break;
}
}
error_on_screen = NO;
touchwin(foot);
wrefresh(foot);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int insert_new_line(unsigned char *line,int len,long num_lines,bool stay)
#else
int insert_new_line(line,len,num_lines,stay)
unsigned char *line;
int len;
long num_lines;
bool stay;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
long true_line;
LINE *curr,*save_curr;
unsigned short x,y;
bool on_bottom=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:insert_new_line");
#endif
/*---------------------------------------------------------------------*/
/* Check from which window the command was issued and make adjustments */
/* as required. */
/* Commands issued from the command window relate to the current line, */
/* commands issued from either the prefix or main window relate to the */
/* focus line. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_MAIN)
{
true_line = CURRENT_VIEW->focus_line;
}
if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
{
true_line = CURRENT_VIEW->focus_line;
}
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| in_profile)
{
true_line = CURRENT_VIEW->current_line;
}
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Copy the contents of the new line into rec so it gets displayed when*/
/* show_page() is called. */
/*---------------------------------------------------------------------*/
/* memcpy(rec,line,len);
rec_len = len; */
/*---------------------------------------------------------------------*/
/* If we are on the 'Bottom of File' line reduce the true_line by 1 */
/* so that the new line is added before the bottom line. */
/*---------------------------------------------------------------------*/
if (true_line == CURRENT_FILE->number_lines+1)
{
true_line--;
on_bottom = YES;
}
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for the true_line. */
/* This is the line after which the line(s) are to be added. */
/*---------------------------------------------------------------------*/
curr = ll_find(CURRENT_FILE->first_line,true_line);
/*---------------------------------------------------------------------*/
/* Insert into the linked list the number of lines specified. All lines*/
/* will contain a blank line and a length of zero. */
/*---------------------------------------------------------------------*/
save_curr = curr;
for (i=0;i<num_lines;i++)
{
if ((curr = add_line(CURRENT_FILE->first_line,curr,line,len)) == NULL)
{
display_error(30,(unsigned char *)"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
}
/*---------------------------------------------------------------------*/
/* Fix the positioning of the marked block (if there is one and it is */
/* in the current view). */
/*---------------------------------------------------------------------*/
adjust_marked_block(YES,true_line,num_lines);
/*---------------------------------------------------------------------*/
/* Increment the number of lines counter for the current file and the */
/* number of alterations. */
/*---------------------------------------------------------------------*/
increment_alt();
CURRENT_FILE->number_lines += num_lines;
/*---------------------------------------------------------------------*/
/* Sort out focus and current line. */
/*---------------------------------------------------------------------*/
CURRENT_VIEW->focus_line++;
if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
{
if (!in_profile)
getyx(CURRENT_WINDOW,y,x);
if (on_bottom)
{
CURRENT_VIEW->focus_line--;
CURRENT_VIEW->current_line++;
}
else if (y == CURRENT_SCREEN.rows - 1)
{
CURRENT_VIEW->current_line++;
}
}
else
if (on_bottom)
{
CURRENT_VIEW->focus_line--;
CURRENT_VIEW->current_line++;
}
/*---------------------------------------------------------------------*/
/* If the current verify settings are not = 1, set them to there. */
/*---------------------------------------------------------------------*/
if (!stay)
{
if (CURRENT_VIEW->verify_col != 1)
CURRENT_VIEW->verify_col = 1;
if (CURRENT_VIEW->verify_start != 1)
CURRENT_VIEW->verify_start = 1;
}
/*---------------------------------------------------------------------*/
/* If we are in the main window, set up the new focus line to be */
/* processed. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
{
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (!stay)
{
i = memne(save_curr->line,' ',save_curr->length);
if (i == (-1))
x = 0;
else
x = i;
}
if (!in_profile)
wmove(CURRENT_WINDOW,y,x);
}
pre_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Re-display the main window. */
/*---------------------------------------------------------------------*/
show_page();
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
int parse_colours(char *attrib,chtype *pfg,chtype *pbg,chtype *pmod)
#else
int parse_colours(attrib,pfg,pbg,pmod)
char *attrib;
chtype *pfg;
chtype *pbg;
chtype *pmod;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
struct attributes
{
unsigned char *attrib;
short attrib_min_len;
chtype actual_attrib;
bool attrib_modifier;
bool attrib_allowed_on_mono;
};
typedef struct attributes ATTRIBS;
#ifdef COLOR_CURSES
#define NO_ATTRIBS 13
#else
#define NO_ATTRIBS 5
#endif
static ATTRIBS valid_attribs[NO_ATTRIBS]=
{
#ifdef COLOR_CURSES
{(unsigned char *)"black",3,COLOR_BLACK,FALSE,FALSE},
{(unsigned char *)"blue",3,COLOR_BLUE,FALSE,FALSE},
{(unsigned char *)"green",1,COLOR_GREEN,FALSE,FALSE},
{(unsigned char *)"cyan",1,COLOR_CYAN,FALSE,FALSE},
{(unsigned char *)"red",3,COLOR_RED,FALSE,FALSE},
{(unsigned char *)"magenta",1,COLOR_MAGENTA,FALSE,FALSE},
{(unsigned char *)"yellow",1,COLOR_YELLOW,FALSE,FALSE},
{(unsigned char *)"white",1,COLOR_WHITE,FALSE,FALSE},
#endif
{(unsigned char *)"normal",3,A_NORMAL,TRUE,TRUE},
{(unsigned char *)"blink",3,A_BLINK,TRUE,TRUE},
{(unsigned char *)"bold",2,A_BOLD,TRUE,TRUE},
{(unsigned char *)"reverse",3,A_REVERSE,TRUE,TRUE},
{(unsigned char *)"underline",1,A_UNDERLINE,TRUE,TRUE},
};
register int i;
int num_colours = 0;
chtype fg = (chtype)0;
chtype bg = (chtype)0;
chtype mod = (chtype)0;
char *p;
bool found;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:parse_colours");
#endif
p = strtok(attrib," ");
while(p != NULL)
{
found = FALSE;
for (i=0;i<NO_ATTRIBS;i++)
{
if (equal(valid_attribs[i].attrib,p,valid_attribs[i].attrib_min_len))
{
found = TRUE;
if (valid_attribs[i].attrib_modifier)
{
mod |= valid_attribs[i].actual_attrib;
break;
}
else
switch(num_colours)
{
case 0: fg = valid_attribs[i].actual_attrib;
num_colours++;
break;
case 1: bg = valid_attribs[i].actual_attrib;
num_colours++;
break;
default:display_error(1,(unsigned char *)p);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
break;
}
break;
}
}
if (!found)
{
display_error(1,(unsigned char *)p);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
p = strtok(NULL," ");
}
*pfg = fg;
*pbg = bg;
*pmod = mod;
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/***********************************************************************/
#ifdef PROTO
void set_colour(int area,chtype fg,chtype bg,chtype mod)
#else
void set_colour(area,fg,bg,mod)
int area;
chtype fg;
chtype bg;
chtype mod;
#endif
/***********************************************************************/
{
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:set_colour");
#endif
#ifdef COLOR_CURSES
if (has_colors())
{
init_pair(area+1,fg,bg);
colour[area] = COLOR_PAIR(area+1) | mod;
}
else
colour[area] = mod;
#else
colour[area] = mod;
#endif
#ifdef TRACE
trace_return();
#endif
return;
}